﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;

namespace PropertyCreator
{
    public partial class Form1 : Form
    {
        IList<Member> list = null;
        public Form1()
        {
            InitializeComponent();
            saveFileDialog1.FileOk += new CancelEventHandler(saveFileDialog1_FileOk);
        }

        private void btnCreate_Click(object sender, EventArgs e)
        {
            list = new List<Member>();
            Regex regex = new Regex("[A-Z]{1}[a-z0-9]*");
            string Tab = "    ";    //Table占位符
            try
            {
                string[] lines = txtSrc.Text.Split('\n');
                foreach (string s in lines)
                {
                    if (String.IsNullOrEmpty(s))
                        continue;
                    string[] tmps = s.Trim().Split(new char[] { ' ' }, 4);
                    Member m = new Member(tmps[0], tmps[1]);
                    if (tmps.Length == 3)
                    {
                        if (tmps[2].StartsWith("//"))
                            m.Comment = tmps[2].Remove(0, 2);
                        else
                        {
                            m.Length = tmps[2];
                            m.Comment = string.Empty;
                        }
                    }
                    else if (tmps.Length == 4)
                    {
                        m.Length = tmps[2];
                        m.Comment = tmps[3].StartsWith("//") ? tmps[3].Remove(0, 2) : tmps[3];
                    }
                    list.Add(m);
                }
            }
            catch (Exception)
            {
            }
            StringBuilder sb = new StringBuilder()
                .Append("using System;").Append(Environment.NewLine)
                .Append(Environment.NewLine)
                .Append("namespace ").Append(txtNamespace.Text).Append(Environment.NewLine)
                .Append("{").Append(Environment.NewLine)
                .Append(Tab).Append("public class ").Append(txtClassName.Text).Append(Environment.NewLine)
                .Append(Tab).Append("{").Append(Environment.NewLine)
                .Append(Tab).Append(Tab).Append("#region 属性访问常量").Append(Environment.NewLine);

            //生成Const访问常量
            foreach (Member m in list)
            {
                StringBuilder tmp = new StringBuilder();
                if (!string.IsNullOrEmpty(m.Comment))
                {
                    tmp.Append(Tab).Append(Tab).Append("/// <summary>").Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// ").Append(m.Comment).Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// </summary>").Append(Environment.NewLine);
                }
                tmp.Append(Tab).Append(Tab).Append("public const string ");
                MatchCollection mc = regex.Matches(m.Name); //大写字母拆分字符串
                bool begin = true;
                foreach (Match em in mc)
                {
                    if (begin)
                    {
                        tmp.Append(em.Value.ToUpper());
                        begin = false;
                    }
                    else
                        tmp.Append("_").Append(em.Value.ToUpper());
                }
                tmp.Append(" = \"").Append(m.Name).Append("\";").Append(Environment.NewLine);
                sb.Append(tmp);
            }
            sb.Append(Tab).Append(Tab).Append("#endregion").Append(Environment.NewLine)
                .Append(Environment.NewLine)
                .Append(Tab).Append(Tab).Append("#region 成员").Append(Environment.NewLine);
            //生成成员
            foreach (Member m in list)
            {
                StringBuilder tmp = new StringBuilder().Append(Tab).Append(Tab).Append("private ");
                tmp.Append(m.Type).Append(" _").Append(m.Name).Append(";");
                if (!string.IsNullOrEmpty(m.Comment))
                {
                    tmp.Append(Tab).Append("//").Append(m.Comment);
                }
                tmp.Append(Environment.NewLine);
                sb.Append(tmp);
            }

            sb.Append(Tab).Append(Tab).Append("#endregion").Append(Environment.NewLine)
                .Append(Environment.NewLine)
                .Append(Tab).Append(Tab).Append("#region 构造方法").Append(Environment.NewLine);
            //生成构造函数
            if (true)
            {
                StringBuilder tmp = new StringBuilder();

                //空构造函数
                //参数注释
                tmp.Append(Tab).Append(Tab).Append("/// <summary>").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("/// 空构造方法").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("/// </summary>").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("public ").Append(txtClassName.Text).Append("() { } ").Append(Environment.NewLine).Append(Environment.NewLine);

                //参数注释
                tmp.Append(Tab).Append(Tab).Append("/// <summary>").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("/// 全参数构造方法").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("/// </summary>").Append(Environment.NewLine);
                foreach (Member m in list)
                {
                    tmp.Append(Tab).Append(Tab).Append("/// <param name=\"").Append(m.Name).Append("\">").Append(m.Comment).Append("</param>").Append(Environment.NewLine);
                }
                //构造方法
                tmp.Append(Tab).Append(Tab).Append("public ").Append(txtClassName.Text).Append("(");
                foreach (Member m in list)
                {
                    tmp.Append(m.Type).Append(" ").Append(m.Name).Append(", ");
                }
                tmp.Remove(tmp.Length - 2, 2);
                tmp.Append(")").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("{").Append(Environment.NewLine);
                foreach (Member m in list)
                {
                    tmp.Append(Tab).Append(Tab).Append(Tab).Append("this._").Append(m.Name).Append(" = ").Append(m.Name).Append(";").Append(Environment.NewLine);
                }

                tmp.Append(Tab).Append(Tab).Append("}").Append(Environment.NewLine).Append(Environment.NewLine);

                sb.Append(tmp);
            }

            sb.Append(Tab).Append(Tab).Append("#endregion").Append(Environment.NewLine)
                .Append(Environment.NewLine)
                .Append(Tab).Append(Tab).Append("#region 属性").Append(Environment.NewLine);

            //生成属性
            foreach (Member m in list)
            {
                StringBuilder tmp = new StringBuilder();
                if (!string.IsNullOrEmpty(m.Comment))
                {
                    tmp.Append(Tab).Append(Tab).Append("/// <summary>").Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// ").Append(m.Comment).Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// </summary>").Append(Environment.NewLine);
                }
                tmp.Append(Tab).Append(Tab).Append("public ");
                if (chkVirtual.Checked)
                {
                    tmp.Append("virtual ");
                }
                tmp.Append(m.Type).Append(" ").Append(m.Name).Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("{").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append(Tab).Append("set { this._").Append(m.Name).Append(" = value; }").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append(Tab).Append("get { return _").Append(m.Name).Append("; }").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("}").Append(Environment.NewLine);
                tmp.Append(Environment.NewLine);
                sb.Append(tmp);
            }
            sb.Append(Tab).Append(Tab).Append("#endregion").Append(Environment.NewLine);

            //结尾反括号
            sb.Append(Environment.NewLine);
            sb.Append(Tab).Append("}").Append(Environment.NewLine); //类反括号
            sb.Append("}"); //名字空间反括号
            txtDect.Text = sb.ToString();
        }

        private void txtSrc_KeyDown(object sender, KeyEventArgs e)
        {
            if ((Control.ModifierKeys & Keys.Control) != 0 && e.KeyCode == Keys.A)
            {
                txtSrc.SelectAll();
            }
        }

        private void txtDect_KeyDown(object sender, KeyEventArgs e)
        {
            if ((Control.ModifierKeys & Keys.Control) != 0 && e.KeyCode == Keys.A)
            {
                txtDect.SelectAll();
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            saveFileDialog1.Filter = "C#(*.cs)|*.cs";
            saveFileDialog1.RestoreDirectory = true;
            saveFileDialog1.ShowDialog();
        }

        void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            if (chkHbm.Checked)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>").Append(Environment.NewLine);
                sb.Append("<hibernate-mapping xmlns=\"urn:nhibernate-mapping-2.2\"");
                if (chkLazy.Checked)
                    sb.Append("  default-lazy=\"true\"");
                sb.Append(">").Append(Environment.NewLine);
                sb.Append("<class name=\"")
                    .Append(txtNamespace.Text.Trim())
                    .Append(".")
                    .Append(txtClassName.Text.Trim())
                    .Append(", ")
                    .Append(txtAssembly.Text.Trim())
                    .Append("\" table=\"")
                    .Append(txtTable.Text.Trim())
                    .Append("\"");
                if (chkDynamicUpdate.Checked)
                    sb.Append(" dynamic-update=\"true\"");
                sb.Append(">").Append(Environment.NewLine);
                //属性
                for (int i = 0; i < list.Count; i++)
                {
                    if (i == 0)
                    {
                        sb.Append("<id name=\"").Append(list[i].Name).Append("\" column=\"").Append(list[i].Name).Append("\" type=\"").Append(list[i].Type).Append("\"");
                        if (!string.IsNullOrEmpty(list[i].Length))
                        {
                            sb.Append(" length=\"").Append(list[i].Length).Append("\"");
                        }
                        sb.Append(" unsaved-value=\"0\">").Append(Environment.NewLine);
                        sb.Append("<generator class=\"native\" />").Append(Environment.NewLine);
                        sb.Append("</id>").Append(Environment.NewLine);
                    }
                    else
                    {
                        sb.Append("<property name=\"").Append(list[i].Name).Append("\" column=\"").Append(list[i].Name).Append("\" type=\"").Append(list[i].Type).Append("\"");
                        if (!string.IsNullOrEmpty(list[i].Length))
                        {
                            sb.Append(" length=\"").Append(list[i].Length).Append("\"");
                        }
                        sb.Append("/>").Append(Environment.NewLine);
                    }
                }
                sb.Append("</class>").Append(Environment.NewLine);
                sb.Append("</hibernate-mapping>").Append(Environment.NewLine);

                File.WriteAllText(saveFileDialog1.FileName.Replace(".cs", ".hbm.xml"), sb.ToString(), System.Text.Encoding.Default);
            }

            File.WriteAllText(saveFileDialog1.FileName, txtDect.Text, System.Text.Encoding.Default);

            MessageBox.Show("生成成功");
        }

        private void btnInMode_Click(object sender, EventArgs e)
        {
            list = new List<Member>();
            Regex regex = new Regex("[A-Z]{1}[a-z0-9]*");
            string Tab = "    ";    //Table占位符
            try
            {
                string[] lines = txtSrc.Text.Split('\n');
                foreach (string s in lines)
                {
                    if (String.IsNullOrEmpty(s))
                        continue;
                    string[] tmps = s.Trim().Split(new char[] { ' ' }, 4);
                    Member m = new Member(tmps[0], tmps[1]);
                    if (tmps.Length == 3)
                    {
                        if (tmps[2].StartsWith("//"))
                            m.Comment = tmps[2].Remove(0, 2);
                        else
                        {
                            m.Length = tmps[2];
                            m.Comment = string.Empty;
                        }
                    }
                    else if (tmps.Length == 4)
                    {
                        m.Length = tmps[2];
                        m.Comment = tmps[3].StartsWith("//") ? tmps[3].Remove(0, 2) : tmps[3];
                    }
                    list.Add(m);
                }
            }
            catch (Exception)
            {
            }
            StringBuilder sb = new StringBuilder()
                .Append("using System;").Append(Environment.NewLine)
                .Append(Environment.NewLine)
                .Append("namespace ").Append(txtNamespace.Text).Append(Environment.NewLine)
                .Append("{").Append(Environment.NewLine)
                .Append(Tab).Append("public class ").Append(txtClassName.Text).Append(Environment.NewLine)
                .Append(Tab).Append("{").Append(Environment.NewLine)
                .Append(Tab).Append(Tab).Append("#region 构造函数").Append(Environment.NewLine);
            //生成构造函数
            if (true)
            {
                StringBuilder tmp = new StringBuilder();

                //空构造函数
                tmp.Append(Tab).Append(Tab).Append("public ").Append(txtClassName.Text).Append("() { } ").Append(Environment.NewLine).Append(Environment.NewLine);

                //参数注释
                tmp.Append(Tab).Append(Tab).Append("/// <summary>").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("/// 全参数构造方法").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("/// </summary>").Append(Environment.NewLine);
                foreach (Member m in list)
                {
                    tmp.Append(Tab).Append(Tab).Append("/// <param name=\"").Append(m.Name).Append("\">").Append(m.Comment).Append("</param>").Append(Environment.NewLine);
                }
                //构造方法
                tmp.Append(Tab).Append(Tab).Append("public ").Append(txtClassName.Text).Append("(");
                foreach (Member m in list)
                {
                    tmp.Append(m.Type).Append(" ").Append(m.Name).Append(", ");
                }
                tmp.Remove(tmp.Length - 2, 2);
                tmp.Append(")").Append(Environment.NewLine);
                tmp.Append(Tab).Append(Tab).Append("{").Append(Environment.NewLine);
                foreach (Member m in list)
                {
                    tmp.Append(Tab).Append(Tab).Append(Tab).Append("this.").Append(m.Name).Append(" = ").Append(m.Name).Append(";").Append(Environment.NewLine);
                }

                tmp.Append(Tab).Append(Tab).Append("}").Append(Environment.NewLine).Append(Environment.NewLine);

                sb.Append(tmp);
            }

            sb.Append(Tab).Append(Tab).Append("#endregion").Append(Environment.NewLine)
                .Append(Environment.NewLine)
                .Append(Tab).Append(Tab).Append("#region 属性").Append(Environment.NewLine);

            //生成属性
            foreach (Member m in list)
            {
                StringBuilder tmp = new StringBuilder();
                if (!string.IsNullOrEmpty(m.Comment))
                {
                    tmp.Append(Tab).Append(Tab).Append("/// <summary>").Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// ").Append(m.Comment).Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// </summary>").Append(Environment.NewLine);
                }
                tmp.Append(Tab).Append(Tab).Append("public ");
                tmp.Append(m.Type).Append(" ").Append(m.Name).Append(" { set; get; }").Append(Environment.NewLine);
                tmp.Append(Environment.NewLine);
                sb.Append(tmp);
            }
            sb.Append(Tab).Append(Tab).Append("#endregion").Append(Environment.NewLine);

            //结尾反括号
            sb.Append(Environment.NewLine);
            sb.Append(Tab).Append("}").Append(Environment.NewLine); //类反括号
            sb.Append("}"); //名字空间反括号
            txtDect.Text = sb.ToString();
        }
    }
    class Member
    {
        public Member(string Type, string Name)
        {
            this.Type = Type;
            this.Name = Name;
        }
        public Member(string Type, string Name, string Length, string Comment)
        {
            this.Type = Type;
            this.Name = Name;
            this.Length = Length;
            this.Comment = Comment;
        }
        public string Type { set; get; }
        public string Name { set; get; }
        public string Length { set; get; }
        public string Comment { set; get; }
    }
}